package com.example.shirodemo.config;
import com.example.shirodemo.pojo.SysPermission;
import com.example.shirodemo.pojo.SysRole;
import com.example.shirodemo.pojo.SysUser;
import com.example.shirodemo.repository.SysUserRepository;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

import javax.annotation.Resource;
//shiro中关于用户安全数据的封装   封装用户、角色、权限等信息
public class ShiroRealm extends AuthorizingRealm {
    @Resource
    private SysUserRepository sysUserRepository;

    /**
     *     * 权限配置
     *    
     */
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        //拿到用户信息
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        SysUser adminInfo = (SysUser) principals.getPrimaryPrincipal();
        for (SysRole role : adminInfo.getRoles()) {
            //将角色放入SimpleAuthorizationInfo
            info.addRole(role.getRole());
            //用户拥有的权限
            for (SysPermission p : role.getPermissions()) {
                info.addStringPermission(p.getPermission());
            }
        }
        return info;
    }

    /**
     *     * 进行身份认证,判断用户名密码是否匹配正确
     *    
     */
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //获取用户的输入的账号
        String username = (String) token.getPrincipal();
        //通过username从数据库中查找 User对象，如果找到，
        //Shiro有时间间隔机制，2分钟内不会重复执行该方法
        //获取用户信息
        SysUser userInfo = sysUserRepository.findByName(username);
        if (userInfo == null) {
            return null;
        }
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(
                /**
                                 * 用户名
                                 */
                userInfo,
                /**
                                 * 密码
                                 */
                userInfo.getPassword(),
                /**
                                 * 设置加密凭证   通过username+salt进行
                 加密以及解密适配
                                 *
                 ByteSource.Util.bytes(userInfo.getCredentialsSalt())
                 ,
                           /**
                                 * realm name
                                 */
                getName()
        );
        return info;
    }
}